﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CheckTTS
{
    class SpanAttrsCheckHandle : CheckHandle
    {
        //private const string CHECK_SPAN_ATTRS_EXPRESS = "<span (?=\\s) (?! (?:[^>\"\\']|(?>\".*?\"|\\'.*?\\'))*? (?<=\\s) (?:term|range) \\s*= ) \\s+ (?:\".*?\"|\\'.*?\\'|[^>]*?)+ >'";
        private const string CHECK_SPAN_HEAD_EXPRESS = "<span(?=\\s)(?!(?:[^>\"\\']|\"[^\"]*\"|\\'[^\\']*\\')*?(?<=\\s)(?:term|range)\\s*=)(?!\\s*/?>)\\s+(?:\".*?\"|\\'.*?\\'|[^>]*?)+>";
        //private const string CHECK_ATTRS = "style=“tts:男生1;”";
        //private const string CHECK_ATTRS = "style=“tts:[男声2]|[男声1]|[女生1]|[女生2]?;”";
        private const string CHECK_ATTRS  = "style=\\s*\"tts:.*;\"";
        
        private MainForm mMainForm = null ;
        private List<ErrorInfo> mErrorList = null;
        private Stack<TagInfo> mTagInfoStack = null;
        private RichTextBox mRichTextBox = null;
        private string[] rolesTag = null;
        private string[] emotionsTag = null;
        private string[] backgroundMusicTag = null;
        private string[] soundEffectTag = null;
        private CheckHandle mSuccessor = null;
        public SpanAttrsCheckHandle(MainForm form){
            mMainForm = form ;
            rolesTag = VoiceTag.getVoiceTag(VoiceTag.ROLE_KEY).Split(new Char [] {' '});
            emotionsTag = VoiceTag.getVoiceTag(VoiceTag.EMOTION_KEY).Split(new Char[] { ' ' });
            backgroundMusicTag = VoiceTag.getVoiceTag(VoiceTag.BACKGROUND_MUSIC_KEY).Split(new Char[] { ' ' });
            soundEffectTag = VoiceTag.getVoiceTag(VoiceTag.SOUND_EFFECT_KEY).Split(new Char[] { ' ' });
        }

       public void checkHandle(string content,List<ErrorInfo> errorList,Stack<TagInfo> tagInfoStack,RichTextBox richTextBox)
        {
            mErrorList = errorList;
            mTagInfoStack = tagInfoStack;
            mRichTextBox = richTextBox;
            MatchCollection matchCollection = Regex.Matches(content, CHECK_SPAN_HEAD_EXPRESS); //满足pattern的匹配集合 
            foreach (Match match in matchCollection)
            {
                string value = match.Value;
                value = value.Replace("<span", "");
                value = value.Replace(">","").Trim();

                //没有style属性
                if (string.IsNullOrEmpty(value)) {
                    setError("缺少语音属性标签。",match.Index,"<span".Length);
                    continue;
                }

               MatchCollection matchColl =  Regex.Matches(value, CHECK_ATTRS);
                if (matchColl == null || matchColl.Count == 0)
                {
                    setError("tts语音属性格式不对。", match.Index, value.Length);
                    continue;
                }
                else {
                    foreach (Match tempMatch in matchColl) {
                        string str = tempMatch.Value;
                        try {
                            str = str.Replace("style=", "").Trim();
                            str = str.Replace("\"tts:", "");
                            str = str.Replace(";\"", "");
                        }catch (Exception e) {                  
                            setError("tts语音属性格式不对。", match.Index, value.Length);
                            continue;
                        }

                        if (string.IsNullOrEmpty(str))
                        {
                            setError("tts语音属性值为空。", match.Index + "<span".Length, tempMatch.Value.Length);                          
                            continue;
                        }else {
                            string[] voiceAttrs = Regex.Split(str,"\\s+");
                            string[] allrolse = new string[rolesTag.Length+emotionsTag.Length+backgroundMusicTag.Length+soundEffectTag.Length];

                            rolesTag.CopyTo(allrolse, 0);
                            emotionsTag.CopyTo(allrolse, rolesTag.Length);
                            backgroundMusicTag.CopyTo(allrolse, rolesTag.Length + emotionsTag.Length);
                            soundEffectTag.CopyTo(allrolse, rolesTag.Length+emotionsTag.Length+backgroundMusicTag.Length);

                            for (int i = 0; i < voiceAttrs.Length;i++ )
                            {
                                if (!allrolse.Contains(voiceAttrs[i])) {
                                    setError("语音标签配置有错误：请确定语音标签都是配置文件中的选项。", match.Index + "<span".Length, tempMatch.Value.Length);
                                }
                            }

                            int countRole = voiceAttrs.Count(role => compare(role,rolesTag));
                            if (countRole > 1) {
                                setError("角色标签多于一个", match.Index + "<span".Length, tempMatch.Value.Length);   
                            }

                            int countEmotion= voiceAttrs.Count(role => compare(role, emotionsTag));
                            if (countEmotion > 1)
                            {
                                setError("情绪标签多于一个", match.Index + "<span".Length, tempMatch.Value.Length);
                            }

                            int countBackgroundMusic = voiceAttrs.Count(role => compare(role, backgroundMusicTag));
                            if (countBackgroundMusic > 1)
                            {
                                setError("背景音乐标签多于一个", match.Index + "<span".Length, tempMatch.Value.Length);
                            }

                            int countSoundEffect = voiceAttrs.Count(role => compare(role, soundEffectTag));
                            if (countSoundEffect > 1)
                            {
                                setError("音效标签多于一个", match.Index + "<span".Length, tempMatch.Value.Length);
                            }

                            //if (countRole == 0 && countEmotion == 0 && countBackgroundMusic == 0 && countSoundEffect==0)
                            //{
                            //    setError("语音标签配置有错误：请确定语音标签都是配置文件中的选项。", match.Index + "<span".Length, tempMatch.Value.Length);
                            //}

                        }
                    }
                }

                //
                
                
            }//end of foreach
           
            StringBuilder build = new StringBuilder() ;
            foreach(ErrorInfo error in errorList){
                build.Append(error.errorInfo+"\n");
            }
            mMainForm.error_output_richTextBox.Text = build.ToString();
            // Console.WriteLine("校验文本的长度："+content.Length);
            mMainForm.label_error_count.Text = "发现:" + errorList.Count + "个错误";
        }

       bool compare(string tag,string[] tags) {
           if(tags==null | tags.Length == 0){
               return false;
           }

           bool result = false;
           for (int i = 0; i < tags.Length ;i++ )
           {
               result = result |tag== tags[i];
           }

           return result;
           
       }
        public void setSuccessor(CheckHandle successor)
        {
            mSuccessor = successor;
        }

        public void setError(string error,int offset,int selectLength) {
            ErrorInfo errorInfo = new ErrorInfo();
            errorInfo.index = offset;
            mRichTextBox.Select(offset, selectLength);
            mRichTextBox.SelectionBackColor = Color.Red;
            errorInfo.errorInfo = error;
            mErrorList.Add(errorInfo);
        }
    }
}
